<?php
class UsersController extends AppController {

	var $name = 'Users';
	var $components = array ('Email');
	var $uses = array('User', 'Article', 'Category', 'Suggestion', 'UserCategory');

	function beforeFilter() {
		parent::beforeFilter();
		if ($this->request->is('post') && in_array($this->request->params['action'], array('admin_login', 'login'))) {
			$cacheName = 'auth_failed_' . $this->request->data['User']['username'];
			$this->log(Cache::read($cacheName, 'users_login'), 'debug');
			if (Cache::read($cacheName, 'users_login') >= Configure::read('User.failed_login_limit')) {
				$this->Session->setFlash(__('You have reached maximum limit for failed login attempts. Please try again after a few minutes.'), 'default', array('class' => 'error'));
				$this->redirect(array('action' => $this->request->params['action']));
			}
		}
	}

	/**
	 * beforeRender
	 *
	 * @return void
	 * @access public
	 */
	public function beforeRender() {
		parent::beforeRender();

		if (in_array($this->request->params['action'], array('admin_login', 'login'))) {
			if ($this->request->is('post') && !empty($this->request->data)) {
				$cacheName = 'auth_failed_' . $this->request->data['User']['username'];
				$cacheValue = Cache::read($cacheName, 'users_login');
				Cache::write($cacheName, (int)$cacheValue + 1, 'users_login');
			}
		}
	}

	/**
	 * Login
	 *
	 * @return boolean
	 * @access public
 	*/
	function login() {
		$this->set('title_for_layout', __('Log in'));
		$this->layout = 'login';
		if ($this->request->is('post')) {
			if ($this->Auth->login()) {
				return $this->redirect($this->Auth->redirect());
			} else {
				$this->Session->setFlash($this->Auth->authError, 'default', array(), 'alert alert-error');
				$this->redirect($this->Auth->loginAction);
			}
		}
	}

	function logout() {
		$this->Session->setFlash(__('Log out successful.'), 'default', array('class' => 'success'));
		$this->redirect($this->Auth->logout());
	}

	function dashboard(){
		$topmenuLinkActive = 0;
		$title_for_layout =  __('Dashboard');

		switch($this->Session->read('Auth.User.role')){
			case ROLE_AUTHOR:
				$this->__getAuthorDashboard();
				break;
			case ROLE_EDITOR:
				$this->__getEditorDashboard();
				break;
		}
	}

	function __getAuthorDashboard(){
		//lay cac keyword goi y cho user
		$suggestions = $this->Suggestion->find('all',array(
			'contain' => array('Keyword.Category'),
			'conditions' => array('Suggestion.user_id' => $this->Session->read('Auth.User.id')),
			'order' => 'Suggestion.created DESC',
		));
		if(!empty($suggestions)){
			$categories = array();
			foreach($suggestions as $suggestion){
				if(!isset($categories[$suggestion['Keyword']['Category']['id']])){
					$categories[$suggestion['Keyword']['Category']['id']] = array(
							'categoryTitle' => $suggestion['Keyword']['Category']['title'],
							'keyword' => array()
					);
				}
				$categories[$suggestion['Keyword']['Category']['id']]['keyword'][] = array(
						'keywordId' => $suggestion['Keyword']['id'],
						'keywordTitle' => $suggestion['Keyword']['title']
				);
			}
		}

		$rows = $this->Article->find('all',array(
			'contain'=> array('Category'),
			'fields'=> array('COUNT(Article.id) as number','Category.title'),
			'conditions'=> array('Article.user_id' => $this->Session->read('Auth.User.id')),
			'group' => array('Article.category_id')
		));
		//du lieu cho hien thi bieu do pie
		$totalArticles = $this->Article->find('count',array(
				'recursive'=> -1,
				'fields'=> 'DISTINCT Article.id',
				'conditions'=> array('Article.user_id' => $this->Session->read('Auth.User.id'))
		));

		foreach($rows as $row){
			$articleByCategory[] = (object)array('name' => $row['Category']['title'], 'y' => round($row[0]['number']/$totalArticles,2)*100);
		}

		$acceptedArticles = $this->Article->find('count',array(
				'recursive'=> -1,
				'fields'=> 'DISTINCT Article.id',
				'conditions'=> array('Article.user_id' => $this->Session->read('Auth.User.id'), 'Article.status' => ARTICLE_STATUS_ACCEPTED)
		));

		$postedArticles = $this->Article->find('count',array(
				'recursive'=> -1,
				'fields'=> 'DISTINCT Article.id',
				'conditions'=> array('Article.user_id' => $this->Session->read('Auth.User.id'), 'Article.status' => ARTICLE_STATUS_POSTED)
		));

		$rejectedArticles = $this->Article->find('count',array(
				'recursive'=> -1,
				'fields'=> 'DISTINCT Article.id',
				'conditions'=> array('Article.user_id' => $this->Session->read('Auth.User.id'), 'Article.status' => ARTICLE_STATUS_REJECTED)
		));

		//du lieu hien thi bieu do cot
		//tao du lieu mac dinh
		$i = 0;
		$firstDayWeek = strtotime('monday this week');
		$dataColumnChart['week'][date('j',$firstDayWeek)] = 0;
		while($i < 7){
			$i++;
			$dataColumnChart['week'][date('j',strtotime($i.' day', $firstDayWeek))] = 0;
		}
		$lastDayMonth = cal_days_in_month(CAL_GREGORIAN, date('m'), date('Y'));
		for($i=1; $i<= $lastDayMonth; $i++){
			$dataColumnChart['month'][$i] = 0;
		}
		for($i=1; $i <= 12; $i++){
			$dataColumnChart['year'][$i] = 0;
		}


		$articlesInWeek = $this->Article->find('all',array(
			'recursive' => -1,
			'fields' => array('DAY(created) as day', 'COUNT(id) as number'),
			'conditions' => array(
				'Article.user_id' => $this->Session->read('Auth.User.id'),
				'Article.created >=' => date('Y-m-d H:i:s',strtotime('monday this week')),
				'Article.created <=' => date('Y-m-d H:i:s')
		),
			'group' => 'DAY(created)'
			));

			foreach($articlesInWeek as $day){
				$dataColumnChart['week'][$day[0]['day']] = $day[0]['number'];
			}

			$articlesInMonth = $this->Article->find('all',array(
		'recursive' => -1,
		'fields' => array('DAY(created) as day', 'COUNT(id) as number'),
		'conditions' => array(
			'Article.user_id' => $this->Session->read('Auth.User.id'),
			'MONTH(Article.created) =' => date('m'),
			'YEAR(Article.created) =' => date('Y')
			),
		'group' => 'DAY(created)'
		));

		foreach($articlesInMonth as $day){
			$dataColumnChart['month'][$day[0]['day']] = $day[0]['number'];
		}

		$articlesInYear = $this->Article->find('all',array(
		'recursive' => -1,
		'fields' => array('MONTH(created) as month', 'COUNT(id) as number'),
		'conditions' => array(
			'Article.user_id' => $this->Session->read('Auth.User.id'),
			'YEAR(Article.created) =' => date('Y')
		),
		'group' => 'MONTH(created)'
		));

		foreach($articlesInYear as $month){
			$dataColumnChart['year'][$month[0]['month']] = $month[0]['number'];
		}
		$this->set(compact('title_for_layout', 'topmenuLinkActive', 'totalArticles', 'acceptedArticles',
			'postedArticles', 'rejectedArticles', 'articleByCategory', 'categories', 'dataColumnChart', 'firstDayWeek'));
		$this->render('author_dashboard');
	}

	function __getEditorDashboard(){
		$categories = $this->UserCategory->find('list', array(
				'recursive'=> -1,
				'conditions'=> array('UserCategory.user_id' => $this->Session->read('Auth.User.id')),
				'fields'=> array('UserCategory.category_id')
		));

		$users = $this->User->find('list', array(
				'recursive'=> -1,
				'conditions'=> array('User.role' => ROLE_AUTHOR),
				'fields'=> array('User.id')
		));
		//du lieu cho hien thi bieu do pie
		$totalArticles = $this->Article->find('count',array(
				'recursive'=> -1,
				'fields'=> 'DISTINCT Article.id',
				'conditions'=> array(
					'Article.user_id' => $users,
					'Article.category_id'=> $categories,
					'OR'=> array(
		array('Article.checker'=> null,'Article.status' => ARTICLE_STATUS_POSTED),
		array('Article.checker'=> $this->Session->read('Auth.User.id'))
		)
		)
		));

		$checkedArticles = $this->Article->find('count',array(
				'recursive'=> -1,
				'fields'=> 'DISTINCT Article.id',
				'conditions'=> array(
					'Article.user_id' => $users,
					'Article.category_id'=> $categories,
					'Article.checker'=> $this->Session->read('Auth.User.id')
		)
		));
			
		$uncheckArticles = $this->Article->find('count',array(
			'recursive'=> -1,
			'fields'=> 'DISTINCT Article.id',
			'conditions'=> array(
				'Article.user_id' => $users,
				'Article.category_id'=> $categories,
				'Article.checker'=> null,
				'Article.status' => ARTICLE_STATUS_POSTED
		)
		));
			
		$recentArticles = $this->Article->find('count',array(
			'recursive'=> -1,
			'fields'=> 'DISTINCT Article.id',
			'conditions'=> array(
				'Article.user_id' => $users,
				'Article.category_id'=> $categories,
				'Article.checker'=> $this->Session->read('Auth.User.id'),
				'DATE(Article.check_time)' => date('Y-m-d')
		)
		));
			
		$dataPieChart = array(
		(object)array('name'=> __('Checked article'), 'y'=> round($checkedArticles/$totalArticles, 2)*100),
		(object)array('name'=> __('Uncheck article'), 'y'=> round($uncheckArticles/$totalArticles, 2)*100)
		);


		//du lieu hien thi bieu do cot
		//tao du lieu mac dinh
		$i = 0;
		$dateTime = new \DateTime(date('Y-m-d'));
		$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
		$firstDayWeek = $monday->getTimestamp();
		$dataColumnChart['week'][date('j',$firstDayWeek)] = 0;
		while($i < 7){
			$i++;
			$dataColumnChart['week'][date('j',strtotime($i.' day', $firstDayWeek))] = 0;
		}
		$lastDayMonth = cal_days_in_month(CAL_GREGORIAN, date('m'), date('Y'));
		for($i=1; $i<= $lastDayMonth; $i++){
			$dataColumnChart['month'][$i] = 0;
		}
		for($i=1; $i <= 12; $i++){
			$dataColumnChart['year'][$i] = 0;
		}


		$articlesInWeek = $this->Article->find('all',array(
			'recursive' => -1,
			'fields' => array('DAY(check_time) as day', 'COUNT(id) as number'),
			'conditions' => array(
				'Article.user_id' => $users,
				'Article.category_id'=> $categories,
				'Article.checker'=> $this->Session->read('Auth.User.id'),
				'Article.check_time >=' => date('Y-m-d H:i:s',$firstDayWeek),
				'Article.check_time <=' => date('Y-m-d H:i:s')
		),
			'group' => 'DAY(check_time)'
			));

			foreach($articlesInWeek as $day){
				$dataColumnChart['week'][$day[0]['day']] = $day[0]['number'];
			}

			$articlesInMonth = $this->Article->find('all',array(
			'recursive' => -1,
			'fields' => array('DAY(check_time) as day', 'COUNT(id) as number'),
			'conditions' => array(
				'Article.user_id' => $users,
				'Article.category_id'=> $categories,
				'Article.checker'=> $this->Session->read('Auth.User.id'),
				'MONTH(Article.check_time) =' => date('m'),
				'YEAR(Article.check_time) =' => date('Y')
			),
			'group' => 'DAY(check_time)'
			));

			foreach($articlesInMonth as $day){
				$dataColumnChart['month'][$day[0]['day']] = $day[0]['number'];
			}

			$articlesInYear = $this->Article->find('all',array(
			'recursive' => -1,
			'fields' => array('MONTH(check_time) as month', 'COUNT(id) as number'),
			'conditions' => array(
				'Article.user_id' => $users,
				'Article.category_id'=> $categories,
				'Article.checker'=> $this->Session->read('Auth.User.id'),
				'YEAR(Article.check_time) =' => date('Y')
			),
			'group' => 'MONTH(check_time)'
			));

			foreach($articlesInYear as $month){
				$dataColumnChart['year'][$month[0]['month']] = $month[0]['number'];
			}
			$this->set(compact('title_for_layout', 'topmenuLinkActive', 'totalArticles', 'checkedArticles',
			'recentArticles', 'uncheckArticles', 'dataPieChart', 'dataColumnChart', 'firstDayWeek'));
			$this->render('editor_dashboard');
	}


	/**
	 * Admin dashboard
	 * @author Tucq
	 * Added 27-06-2012
	 */
	function admin_dashboard(){
		$this->set('title_for_layout', __('Admin Dashboard'));
	}

	/**
	 * List Users
	 * @author Tucq
	 *
	 */
	function admin_index() {
		$this->set('title_for_layout', __('List Users'));

		$data = $this->params['url'];
		unset($data['url']);
		$conditions = array();
		$conditions['is_deleted'] = 0;
		if (!empty($data['conditions'])) {
			if ($data['conditions']['showTrash']) {
				unset($conditions['is_deleted']);
			}

			if (!empty($data['conditions']['keyword'])) {
				$conditions[] = array('OR' => array(
					'LOCATE(\''. $data['conditions']['keyword'] . '\', username) >' => 0,
					'LOCATE(\''. $data['conditions']['keyword'] . '\', name) >' => 0,
					'LOCATE(\''. $data['conditions']['keyword'] . '\', email) >' => 0,
				));
			}
		}

		$conditions['role <>'] = ROLE_ADMINISTRATOR;

		$this->paginate = array(
			'limit' => 5, 
			'recursive' => -1,
			'order' => array('role', 'is_deleted'),
			'conditions' => $conditions
		);
		$users = $this->paginate('User');
		$this->set(compact('users'));
	}

	/**
	 * Create new User
	 * @author Tucq
	 */
	function admin_add() {
		$this->set('title_for_layout', __('Create new User'));

		if (!empty($this->request->data)) {
			$data = $this->request->data;
			$this->User->set($data);
			if ($this->User->validates()) {
				$data['User']['activation_key'] = md5(uniqid());
				$data['User']['password'] = $this->Auth->password($data['User']['pwd']);
				unset($data['User']['pwd']);

				$this->User->create();
				$this->User->save($data);

				$this->Session->setFlash(__('User saved successful'), 'default', array('class' => 'alert alert-success'));
				$this->redirect(array('action'=>'index'));
			} else {
				$this->Session->setFlash(__('User could not be saved. Please, try again!'), 'default', array('class' => 'alert alert-error'));
			}
		}
	}

	/**
	 * Edit User
	 * @author Tucq
	 * @todo : 	Admin can edit manager, user
	 * 			SA can edit all, except SA
	 */
	function admin_edit($id = null) {
		$this->set('title_for_layout', __('Edit User'));
		$user = $this->User->find('first', array(
			'recursive' => -1,
			'conditions' => array('id' => $id)
		));
		if (empty($id) || empty($user)) {
			$this->Session->setFlash((__('Invalid user')));
			$this->redirect(array('action' => 'index','admin' => true));
		}

		if (!empty($this->request->data)) {
			if (empty($this->request->data['User']['password'])) {
				unset($this->request->data['User']['password']);
			} else {
				$this->request->data['User']['password'] = $this->Auth->password($this->request->data['User']['password']);
			}
			$this->User->id = $id;

			if ($this->User->save($this->request->data)) {
				$this->Session->setFlash('Update user successful', 'default', array('class' => 'alert alert-success'));
				$this->redirect(array('action' => 'index','admin' => true));
			} else {
				$this->Session->setFlash('Update user failed', 'default', array('class' => 'alert alert-error'));
			}

		}
		$this->set(compact('user'));
	}

	/**
	 * Delete "logical" user
	 * @author Tucq
	 * Added 02-07-2012
	 * Admin can delete manager, uer
	 * SA can delete all, except SA
	 */
	function admin_delete($id = null) {
		$this->autoRender = false;
		if (!$id) {
			$this->Session->setFlash(__('Invalid User'), 'default', array('class' => 'alert alert-error'));
			$this->redirect(array('action' => 'index'));
		}

		$this->User->id = $id;
		if ($this->User->saveField('is_deleted', IS_DELETED)) {
			$this->Session->setFlash(__('User deleted successful'),
				'default',
			array('class' => 'alert alert-success'));

		} else {
			$this->Session->setFlash(__('User deleted failed! Please try again.'),
				'default',
			array('class' => 'alert alert-error'));
		}
		$this->redirect(array('action' => 'index', 'admin' => true));
	}

	/**
	 * Recover user
	 * @author Tucq
	 * Added 31-07-2012
	 * Admin re-active user that had been deleted
	 */
	function admin_recover($id = null) {
		$this->autoRender = false;
		if (!$id) {
			$this->Session->setFlash(__('Invalid User'), 'default', array('class' => 'alert alert-error'));
			$this->redirect(array('action' => 'index', 'admin' => true));
		}

		$this->User->id = $id;
		if ($this->User->saveField('is_deleted', NOT_DELETED)) {
			$this->Session->setFlash(__('User recovered successful'),
				'default',
			array('class' => 'alert alert-success'));

		} else {
			$this->Session->setFlash(__('User recover failed! Please try again.'),
				'default',
			array('class' => 'alert alert-error'));
		}
		$this->redirect(array('action' => 'index', 'admin' => true));
	}

	/**
	 * User Profile
	 * @author Tucq
	 * Added 02-07-2012
	 */
	function profile() {
		//View current login User (All role) information
		$this->set('title_for_layout', __('Admin Profile'));

		$user = $this->User->find('first', array(
			'recursive' => -1,
			'conditions' => array('id' => $this->Auth->user('id'),
		)));
		if (!empty($this->request->data)) {
			//Get data from client
			$data = $this->request->data;
			if (isset($data['ChangePwd'])) {
				//Change Password
				if (empty($data['ChangePwd']['oldPwd']) || empty($data['ChangePwd']['pwd']) || empty($data['ChangePwd']['confirmPwd'])) {
					//A password field is empty
					$this->Session->setFlash('Error! All password field is required', 'default', array('class' => 'alert alert-error'));
				} elseif ($user['User']['password'] != $this->Auth->password($data['ChangePwd']['oldPwd'])) {
					//Current password is not correct
					$this->Session->setFlash('Current password is wrong', 'default', array('class' => 'alert alert-error'));
				} else {
					if ($data['ChangePwd']['pwd'] != $data['ChangePwd']['confirmPwd']) {
						//New password and it's confirmation are not match
						$this->Session->setFlash('Confirm password is not match with new password', 'default', array('class' => 'alert alert-error'));
					} else {
						$userData['User']['pwd'] = $data['ChangePwd']['pwd'];
						$this->User->set($userData);

						//Validate password field by model
						if ($this->User->validates()) {
							$this->User->id = $user['User']['id'];
							if ($this->User->saveField('password', $this->Auth->password($data['ChangePwd']['pwd']))) {
								//Change password ok
								$this->Session->setFlash('Change user\'s password successful', 'default', array('class' => 'alert alert-success'));
								$this->redirect(array('controller' => 'users', 'action' => 'profile', 'admin' => true));
							} else {
								$this->Session->setFlash('Error. Please try again!', 'default', array('class' => 'alert alert-error'));
							}
						} else {
							//Validate failed
							$this->Session->setFlash('Min Length for password is 6 characters ', 'default', array('class' => 'alert alert-error'));
						}
					}
				}
			}

			if (!empty($data['User'])) {
				//Update Info
				$this->User->id = $user['User']['id'];
				if ($this->User->save($data)) {
					$this->Session->setFlash('Update user successful', 'default', array('class' => 'alert alert-success'));
				} else {
					$this->Session->setFlash('Update user failed', 'default', array('class' => 'alert alert-error'));
				}
			}
		}

		$this->set(compact('user'));
	}

	/**
	 * Admin Profile
	 * @author Tucq
	 * Added 01-08-2012
	 */
	function admin_profile() {
		//View current login User (All role) information
		$this->set('title_for_layout', __('Admin Profile'));

		$user = $this->User->find('first', array(
			'recursive' => -1,
			'conditions' => array('id' => $this->Auth->user('id'),
		)));
		if (!empty($this->request->data)) {
			//Get data from client
			$data = $this->request->data;
			if (isset($data['ChangePwd'])) {
				//Change Password
				if (empty($data['ChangePwd']['oldPwd']) || empty($data['ChangePwd']['pwd']) || empty($data['ChangePwd']['confirmPwd'])) {
					//A password field is empty
					$this->Session->setFlash('Error! All password field is required', 'default', array('class' => 'alert alert-error'));
				} elseif ($user['User']['password'] != $this->Auth->password($data['ChangePwd']['oldPwd'])) {
					//Current password is not correct
					$this->Session->setFlash('Current password is wrong', 'default', array('class' => 'alert alert-error'));
				} else {
					if ($data['ChangePwd']['pwd'] != $data['ChangePwd']['confirmPwd']) {
						//New password and it's confirmation are not match
						$this->Session->setFlash('Confirm password is not match with new password', 'default', array('class' => 'alert alert-error'));
					} else {
						$userData['User']['pwd'] = $data['ChangePwd']['pwd'];
						$this->User->set($userData);

						//Validate password field by model
						if ($this->User->validates()) {
							$this->User->id = $user['User']['id'];
							if ($this->User->saveField('password', $this->Auth->password($data['ChangePwd']['pwd']))) {
								//Change password ok
								$this->Session->setFlash('Change user\'s password successful', 'default', array('class' => 'alert alert-success'));
								$this->redirect(array('controller' => 'users', 'action' => 'profile', 'admin' => true));
							} else {
								$this->Session->setFlash('Error. Please try again!', 'default', array('class' => 'alert alert-error'));
							}
						} else {
							//Validate failed
							$this->Session->setFlash('Min Length for password is 6 characters ', 'default', array('class' => 'alert alert-error'));
						}
					}
				}
			}

			if (!empty($data['User'])) {
				//Update Info
				$this->User->id = $user['User']['id'];
				if ($this->User->save($data)) {
					$this->Session->setFlash('Update user successful', 'default', array('class' => 'alert alert-success'));
				} else {
					$this->Session->setFlash('Update user failed', 'default', array('class' => 'alert alert-error'));
				}
			}
		}

		$this->set(compact('user'));
	}

	function admin_login() {
	$this->set('title_for_layout', __('Admin Login'));
		$this->layout = "admin_login";
		if ($this->request->is('post')) {
			if ($this->Auth->login()) {
				return $this->redirect($this->Auth->redirect());
			} else {
				$this->Session->setFlash($this->Auth->authError, 'default', array(), 'auth');
				$this->redirect($this->Auth->loginAction);
			}
		}
	}

	function admin_logout() {
		$this->Session->setFlash(__('Log out successful.'), 'default', array('class' => 'success'));
		$this->redirect($this->Auth->logout());
	}

}